package net.xdclass.video.controller;

import cn.hutool.core.io.resource.UrlResource;
import com.google.common.net.HttpHeaders;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import net.xdclass.video.entity.domain.Comments;
import net.xdclass.video.mapper.CommentsMapper;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@RestController
public class VideosController {

    private CommentsMapper commentsMapper;
    @GetMapping("/play")
    public void play(HttpServletRequest request, HttpServletResponse response, @RequestParam("url") String videoUrl) throws IOException {
        response.reset();

        String baseUrl = "http://localhost:9090/";
        String resourcePath;

        if (videoUrl.startsWith(baseUrl)) {
            resourcePath = videoUrl.substring(baseUrl.length());
            System.out.println("================" + resourcePath);
        } else {
            resourcePath = videoUrl;
        }

        ClassPathResource videoResource = new ClassPathResource(resourcePath);

        if (!videoResource.exists()) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        long fileLength = videoResource.contentLength();
        String rangeString = request.getHeader("Range");
        long rangeStart = 0;
        long rangeEnd = fileLength - 1;

        if (rangeString != null && rangeString.startsWith("bytes=")) {
            Pattern pattern = Pattern.compile("bytes=(\\d*)-(\\d*)");
            Matcher matcher = pattern.matcher(rangeString);
            if (matcher.find()) {
                String start = matcher.group(1);
                String end = matcher.group(2);
                if (!start.isEmpty()) {
                    rangeStart = Long.parseLong(start);
                }
                if (!end.isEmpty()) {
                    rangeEnd = Long.parseLong(end);
                }
            }
        }

        if (rangeStart > rangeEnd || rangeEnd >= fileLength) {
            response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return;
        }

        long contentLength = rangeEnd - rangeStart + 1;

        response.setHeader("Content-Type", "video/mp4");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + videoResource.getFilename() + "\"");
        response.setHeader("Content-Range", "bytes " + rangeStart + "-" + rangeEnd + "/" + fileLength);
        response.setHeader("Accept-Ranges", "bytes");
        response.setHeader("Content-Length", String.valueOf(contentLength));
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

        try (InputStream inputStream = videoResource.getInputStream();
             OutputStream outputStream = response.getOutputStream()) {
            inputStream.skip(rangeStart);
            byte[] buffer = new byte[1024 * 1024];
            long bytesRead = 0;

            while (bytesRead < contentLength) {
                int len = inputStream.read(buffer, 0, (int)Math.min(buffer.length, contentLength - bytesRead));
                if (len == -1) {
                    break;
                }
                outputStream.write(buffer, 0, len);
                bytesRead += len;
            }
        }
    }
    private final Path rootLocation = Paths.get("src/main/resources/static/files/document");

    @SneakyThrows
    @PostMapping("/apiOne/files/upload")
    public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
        String filename = StringUtils.cleanPath(file.getOriginalFilename());
        if (!Files.exists(rootLocation)) {
            Files.createDirectories(rootLocation);
        }
        try {
            Files.copy(file.getInputStream(), this.rootLocation.resolve(filename));
            // 保存文件信息到数据库
            Comments comments = new Comments();
            comments.setDocumentname(filename);
            comments.setUrl("http://localhost:9090/files/document"+filename);
            comments.setId("8");
            commentsMapper.insert(comments);
            // saveFileMetadata(filename, "uploads/" + filename);
            return ResponseEntity.ok("文件上传成功");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body("文件上传失败");
        }
    }

    @GetMapping("/apiOne/files/")
    public ResponseEntity<List<String>> listUploadedFiles() {
        try {
            List<String> fileList = Files.walk(this.rootLocation, 1)
                    .filter(path -> !path.equals(this.rootLocation))
                    .map(this.rootLocation::relativize)
                    .map(Path::toString)
                    .collect(Collectors.toList());
            return ResponseEntity.ok(fileList);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }

//    @GetMapping("/{filename:.+}")
//    @ResponseBody
//    public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
//        try {
//            Path file = rootLocation.resolve(filename);
//            Resource resource = new UrlResource(file.toUri());
//
//            if (resource.exists() || resource.isReadable()) {
//                return ResponseEntity.ok()
//                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
//                        .body(resource);
//            } else {
//                return ResponseEntity.status(404).body(null);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//            return ResponseEntity.status(500).body(null);
//        }
//    }
}
